home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / DevTools / eText5 / Source / unused4Code / BBC.bproj / BBC.m < prev    next >
Encoding:
Text File  |  1994-07-24  |  16.6 KB  |  657 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //    FILENAME:    BBC.m 
  3. //    SUMMARY:    Implementation of a Billiard-Ball Computation Annotation
  4. //    SUPERCLASS:    Object
  5. //    INTERFACE:    None
  6. //    PROTOCOLS:    <DocNotification,Annotation,Tool,ASCIISupport>
  7. //    AUTHOR:        Rohit Khare
  8. //    COPYRIGHT:    (c) 1994 California Institure of Technology, eText Project
  9. //    COPYRIGHT:    (c) 1992 Rohit Khare (core simulation code)
  10. ///////////////////////////////////////////////////////////////////////////////
  11. //    DESCRIPTION
  12. //        Separated out model from old BilliardView code.
  13. ///////////////////////////////////////////////////////////////////////////////
  14. //    HISTORY
  15. //    05/29/94:    Created as an eText Annotation.
  16. //    1992-93:    Developed for CS20ab.
  17. ///////////////////////////////////////////////////////////////////////////////
  18.  
  19. #import "BBC.h"
  20. /* to allow access without out-of-bound errors and allow wrap-around */
  21. #define state(i,j) (state[(i+vres) %vres][(j+hres)%hres])
  22. #define oldstate(i,j) (oldstate[(i+vres) %vres][(j+hres)%hres])
  23.  
  24. @implementation BBC
  25. + toolAwake:theApp
  26. {
  27.     char        buf[MAXPATHLEN];
  28.     NXBundle    *bundle;
  29.     NXImage        *theIcon;
  30.     
  31.     bundle = [NXBundle bundleForClass:[BBC class]];
  32.     if ([bundle getPath:buf forResource:"N" ofType:"tiff"] ) {
  33.         [[[NXImage alloc] initFromFile:buf] setName:"N"];
  34.     } else {
  35.         NXLogError("Image not found: N");
  36.     }
  37.     if ([bundle getPath:buf forResource:"S" ofType:"tiff"] ) {
  38.         [[[NXImage alloc] initFromFile:buf] setName:"S"];
  39.     } else {
  40.         NXLogError("Image not found: S");
  41.     }
  42.     if ([bundle getPath:buf forResource:"E" ofType:"tiff"] ) {
  43.         [[[NXImage alloc] initFromFile:buf] setName:"E"];
  44.     } else {
  45.         NXLogError("Image not found: E");
  46.     }
  47.     if ([bundle getPath:buf forResource:"W" ofType:"tiff"] ) {
  48.         [[[NXImage alloc] initFromFile:buf] setName:"W"];
  49.     } else {
  50.         NXLogError("Image not found: W");
  51.     }
  52.     if ([bundle getPath:buf forResource:"Trail" ofType:"tiff"] ) {
  53.         [[[NXImage alloc] initFromFile:buf] setName:"Trail"];
  54.     } else {
  55.         NXLogError("Image not found: Trail");
  56.     }
  57.     if ([bundle getPath:buf forResource:"Wall" ofType:"tiff"] ) {
  58.         [[[NXImage alloc] initFromFile:buf] setName:"Wall"];
  59.     } else {
  60.         NXLogError("Image not found: Wall");
  61.     }
  62.     if ([bundle getPath:buf forResource:"Grid" ofType:"tiff"] ) {
  63.         [[[NXImage alloc] initFromFile:buf] setName:"Grid"];
  64.     } else {
  65.         NXLogError("Image not found: Grid");
  66.     }
  67.     if ( [bundle getPath:buf forResource:"BBC" ofType:"tiff"] ) {
  68.         theIcon = [[NXImage alloc] initFromFile:buf];
  69.         [theIcon setName:"BBC"];
  70.     } else {
  71.         NXLogError("Image not found: BBC");
  72.         theIcon = nil;
  73.     }
  74.     [theApp   registerAnnotation: [BBC class] 
  75.                             name: "BBC"
  76.                     RTFDirective: "BBC"
  77.                        menuLabel: "Simulations/Insert BBC..."
  78.                          menuKey: 0
  79.                         menuIcon: (NXImage *) theIcon];
  80.     [theApp registerType:NXCreateFileContentsPboardType("bbc")
  81.                 for:[BBC class]];
  82.     return self;
  83. }
  84.  
  85. - init 
  86. {    char buf[MAXPATHLEN];
  87.     NXRect rt;
  88.     
  89.     [super init];
  90.     state = oldstate = NULL;
  91.     sprintf(buf, "Untitled BBC %d", [NXApp uniqueID]);
  92.     theName = NXUniqueString(buf);
  93.     isAccelerated = NO;
  94.     isEditable = doesShowPath = YES;
  95.     bbcView = [[BilliardView alloc] init];
  96.     [bbcView setAutodisplay:YES];
  97.     [bbcView setBBC:self];
  98.     rt.origin.x = rt.origin.y = 0.0;
  99.     rt.size.width = rt.size.height = 200.0;
  100.     scrollView = [[ScrollView alloc] initFrame:&rt];
  101.     [scrollView setDocView:bbcView];
  102.     [scrollView setCopyOnScroll:YES];
  103.     [[scrollView setVertScrollerRequired:YES] setHorizScrollerRequired:YES];
  104.     dirFwd = YES;
  105.     etDoc = nil;
  106.     hres = 10;
  107.     vres = 10;
  108.     [bbcView setRes:hres :vres];
  109.     return self;
  110. }
  111.  
  112. - initFromPboard:thePboard inDoc:theDoc linked:(BOOL) linked
  113. {
  114.     [self init];
  115.     etDoc = theDoc;
  116.     [etDoc registerNotification:self];
  117.     isLinked = linked;
  118.     if (thePboard != nil) {
  119.         // 2 cases: we have a filename or fcontents on the pboard
  120.         if ([thePboard findAvailableTypeFrom:&NXFilenamePboardType
  121.                     num:1]) 
  122.         {
  123.             char    *path;
  124.             int        len;
  125.             FILE *infile;
  126.             int i,j;
  127.             char c;
  128.             
  129.             isLinked = linked;
  130.             [thePboard readType:NXFilenamePboardType data:&path length:&len];
  131.             if (index(path, '\t')) *index(path, '\t')=0;
  132.             if (isLinked)
  133.                 theName = NXUniqueString(path);
  134.             else theName = NXUniqueString(rindex(path, '/')+1);
  135.             infile = fopen(path,"r");
  136.             fscanf(infile,"Hres %d Vres %d Reps %d\n",&hres,&vres,&i);
  137.             state = malloc(vres* sizeof(char*));
  138.             oldstate = malloc(vres* sizeof(char*));
  139.             i = -1;
  140.             while(++i < vres){
  141.                 state[i] = malloc(hres*sizeof(char));
  142.                 oldstate[i] = malloc(hres*sizeof(char));
  143.                 j = -1;
  144.                 while(++j < hres){
  145.                     fscanf(infile,"%c", &c);
  146.                     switch (c) {
  147.                         case 'O':{    state[i][j] = c;
  148.                                         break;}
  149.                         case 'N':{    state[i][j] = c;
  150.                                         break;}
  151.                         case 'S':{    state[i][j] = c;
  152.                                         break;}
  153.                         case 'W':{    state[i][j] = c;
  154.                                         break;}
  155.                         case 'E':{    state[i][j] = c;
  156.                                         break;}
  157.                         case ';':
  158.                         case '.':
  159.                         default :{    state[i][j] = '.';
  160.                                         break;}
  161.                     }
  162.                 }
  163.                 fscanf(infile,"%c", &c);
  164.             }
  165.             fclose(infile);
  166.             [thePboard deallocatePasteboardData:path length:len];
  167.         } else if ([thePboard findAvailableTypeFrom:&NXFileContentsPboardType 
  168.                     num:1]) {
  169.             NXLogError("Hey! BBC found fileContents WITHOUT a filename");
  170.         } else 
  171.             NXBeep();
  172.     } else {
  173.         int i,j;
  174.         
  175.         state = malloc(vres * sizeof(char*));
  176.         oldstate = malloc(vres * sizeof(char*));
  177.         i = -1;
  178.         while(++i < vres){
  179.             state[i] = malloc(hres*sizeof(char));
  180.             oldstate[i] = malloc(hres*sizeof(char));
  181.             for(j=0; j<hres; j++) state[i][j] = '.';
  182.         }
  183.     }
  184.     [bbcView setRes:hres :vres];
  185.     if ([bbcView window]) {
  186.         NXRect bbcRt, winRt;
  187.         
  188.         [bbcView getBounds:&bbcRt];
  189.         [[bbcView window] getBounds:&winRt];
  190.         if (bbcRt.size.width > (winRt.size.width - 72.0))
  191.             bbcRt.size.width = (winRt.size.width - 72.0);
  192.         if (bbcRt.size.height > (winRt.size.height - 48.0))
  193.             bbcRt.size.height = (winRt.size.height - 48.0);
  194.         [scrollView sizeTo:bbcRt.size.height :bbcRt.size.width];
  195.     }
  196.     return self;
  197. }
  198.  
  199. - free
  200. {
  201.     int i;
  202.     
  203.     [[NXApp inspector] invalidate];
  204.     [etDoc unregisterNotification:self];
  205.     [scrollView free];
  206.     i = -1;
  207.     while(++i < vres){
  208.         free(state[i]);
  209.         free(oldstate[i]);
  210.     }
  211.     free(state);
  212.     free(oldstate);
  213.     return [super free];
  214. }
  215.  
  216. - calcCellSize:(NXSize *)theSize
  217. {    
  218.     NXRect theRect;
  219.     
  220.        [scrollView getBounds:&theRect];
  221.     theSize->width = theRect.size.width;
  222.     theSize->height = theRect.size.height;
  223.     return self;
  224. }
  225.  
  226. - highlight:(const NXRect *)cellFrame inView:controlView lit:(BOOL)flag { return self;}
  227.  
  228. - drawSelf:(const NXRect *)cellFrame inView:controlView
  229. {    
  230.     if ([scrollView superview] == NULL) [controlView addSubview:scrollView];
  231.     [scrollView setBackgroundGray:NX_WHITE];
  232.     [scrollView moveTo:cellFrame->origin.x :cellFrame->origin.y];
  233.     [scrollView display];
  234.     return self;
  235. }
  236.  
  237. - (BOOL) trackMouse:(NXEvent *)theEvent inRect:(const NXRect *)cellFrame
  238.   ofView:controlView
  239. {
  240.     // does this ever get called at all? is the View higher in Responder ch?
  241.     [[NXApp inspector] inspect:[[BBCUI new] setBBC:self]];
  242.     return YES;
  243. }
  244.  
  245. - (NXAtom) name {return theName;}
  246. - (char *) filename {return theName;} // this doesn't work yet
  247. - (BOOL) doesShowPath {return doesShowPath;}
  248. - (BOOL) isAccelerated {return isAccelerated;}
  249. - (BOOL) isEditable {return isEditable;}
  250. - (int) hres {return hres;}
  251. - (int) vres {return vres;}
  252. - (char **) state {return state;}
  253. - setName:(NXAtom) newName {theName = newName; return self;}
  254. - setShowPath:(BOOL) newState {doesShowPath = newState; return self;}
  255. - setAccelerated:(BOOL) newState {isAccelerated = newState; return self;}
  256. - setEditable:(BOOL) newState {isEditable = newState; return self;}
  257. - setRes:(int)h :(int)v
  258. {
  259.     char **newstate, **newoldstate;
  260.     int i,j;
  261.     
  262.     newstate = malloc(v * sizeof(char*));
  263.     newoldstate = malloc(v * sizeof(char*));
  264.     i = -1;
  265.     while(++i < v){
  266.         newstate[i] = malloc(h*sizeof(char));
  267.         newoldstate[i] = malloc(h*sizeof(char));
  268.         for(j=0; j<h; j++){
  269.         if ((i < vres) && (j < hres)) 
  270.             newstate[i][j] = state[i][j];
  271.         else newstate[i][j] = '.';
  272.         }
  273.     }
  274.  
  275.     i = -1;
  276.     while(++i < vres){
  277.         free(state[i]);
  278.         free(oldstate[i]);
  279.     }
  280.     free(state);
  281.     free(oldstate);
  282.     state = newstate;
  283.     oldstate = newoldstate;
  284.     hres = h;
  285.     vres = v;
  286.     [bbcView setRes:h :v];
  287.     if ([bbcView window]) {
  288.         NXRect bbcRt, winRt;
  289.         
  290.         [bbcView getBounds:&bbcRt];
  291.         [[bbcView window] getBounds:&winRt];
  292.         if (bbcRt.size.width > (winRt.size.width - 72.0))
  293.             bbcRt.size.width = (winRt.size.width - 72.0);
  294.         if (bbcRt.size.height > (winRt.size.height - 48.0))
  295.             bbcRt.size.height = (winRt.size.height - 48.0);
  296.         [scrollView sizeTo:bbcRt.size.height :bbcRt.size.width];
  297.     }
  298.     return self;
  299. }
  300. - stepForward 
  301. {
  302.     if (!dirFwd) [self reverse];
  303.     return [self step];
  304. }
  305. - stepBackward 
  306. {
  307.     if (dirFwd) [self reverse];
  308.     return [self step];
  309. }
  310. - step
  311. {
  312.     int i,j, flag;        // flag exists to check for extraordinary 
  313.                         // conditions like collision on both corners
  314.     
  315.     if (state == NULL) return self;
  316.     i = -1;
  317.     while(++i < vres){
  318.         j = -1;
  319.         while(++j < hres){
  320.             oldstate[i][j] = state[i][j];
  321.         }
  322.     }
  323. /* Phase 1: compute new velocities */
  324.     i = vres;
  325.     while(i-- > 0){
  326.         j = -1;
  327.         while(++j < hres){
  328.             switch (state[i][j]) {
  329.                 case 'N':{    flag = 0;
  330.                                 switch (state(i-1,j-1)){
  331.                                     case 'E':
  332.                                     case 'S':
  333.                                     case 'O': {    oldstate[i][j] = 'E';
  334.                                                     flag = 1;
  335.                                                     break;
  336.                                                 }
  337.                                     default:    break;
  338.                                 }
  339.                                 switch (state(i-1,j+1)){
  340.                                     case 'W':
  341.                                     case 'S':
  342.                                     case 'O': {    if (flag){
  343.                                                         oldstate[i][j] = 'S';
  344.                                                     } else {
  345.                                                         oldstate[i][j] = 'W';
  346.                                                     }
  347.                                                     break;
  348.                                                 }
  349.                                     default:    break;
  350.                                 }
  351.                                 break;}
  352.                 case 'S':{    flag = 0;
  353.                                 switch (state(i+1,j-1)){
  354.                                     case 'N':
  355.                                     case 'E':
  356.                                     case 'O': {    oldstate[i][j] = 'E';
  357.                                                     flag = 1;
  358.                                                     break;
  359.                                                 }
  360.                                     default:    break;
  361.                                 }
  362.                                 switch (state(i+1,j+1)){
  363.                                     case 'N':
  364.                                     case 'W':
  365.                                     case 'O': {    if (flag){
  366.                                                         oldstate[i][j] = 'N';
  367.                                                     } else{
  368.                                                         oldstate[i][j] = 'W';
  369.                                                     }
  370.                                                     break;
  371.                                                 }
  372.                                     default:    break;
  373.                                 }
  374.                                 break;}
  375.                 case 'W':{    flag = 0;
  376.                                 switch (state(i-1,j-1)){
  377.                                     case 'E':
  378.                                     case 'S':
  379.                                     case 'O': {    oldstate[i][j] = 'S';
  380.                                                     flag = 1;
  381.                                                     break;
  382.                                                 }
  383.                                     default:    break;
  384.                                 }
  385.                                 switch (state(i+1,j-1)){
  386.                                     case 'E':
  387.                                     case 'N':
  388.                                     case 'O': {    if (flag){
  389.                                                         oldstate[i][j] = 'E';
  390.                                                     } else{
  391.                                                         oldstate[i][j] = 'N';
  392.                                                     }
  393.                                                     break;
  394.                                                 }
  395.                                     default:    break;
  396.                                 }
  397.                                 break;}
  398.                 case 'E':{    flag = 0;
  399.                                 switch (state(i-1,j+1)){
  400.                                     case 'W':
  401.                                     case 'S':
  402.                                     case 'O': {    oldstate[i][j] = 'S';
  403.                                                     flag = 1;
  404.                                                     break;
  405.                                                 }
  406.                                     default:    break;
  407.                                 }
  408.                                 switch (state(i+1,j+1)){
  409.                                     case 'W':
  410.                                     case 'N':
  411.                                     case 'O': {    if (flag){
  412.                                                         oldstate[i][j] = 'W';
  413.                                                     } else{
  414.                                                         oldstate[i][j] = 'N';
  415.                                                     }
  416.                                                     break;
  417.                                                 }
  418.                                     default:    break;
  419.                                 }
  420.                                 break;}
  421.                 }
  422.         }
  423.     }
  424.     
  425. /* Phase 2: move balls */
  426.     i = vres;
  427.     while(i-- > 0){
  428.         j = -1;
  429.         while(++j < hres){
  430.             switch (oldstate[i][j]) {
  431.                 case 'N':{    state[i][j] = ';';
  432.                                 state(i-1,j) = 'N';
  433.                                 break;}
  434.                 case 'S':{    state[i][j] = ';';
  435.                                 state(i+1,j) = 'S';
  436.                                 break;}
  437.                 case 'W':{    state[i][j] = ';';
  438.                                 state(i,j-1) = 'W';
  439.                                 break;}
  440.                 case 'E':{    state[i][j] = ';';
  441.                                 state(i,j+1) = 'E';
  442.                                 break;}
  443.             }
  444.         }
  445.     }
  446.     [bbcView display];
  447.     return self;
  448. }
  449. - reverse
  450. {
  451.     int i,j;
  452.  
  453.     if (state == NULL) {return self;}
  454.     i = vres;
  455.     while(i-- > 0){
  456.         j = -1;
  457.         while(++j < hres){
  458.             switch (state[i][j]) {
  459.                 case 'N':{    state[i][j] = 'S';
  460.                                 break;}
  461.                 case 'S':{    state[i][j] = 'N';
  462.                                 break;}
  463.                 case 'W':{    state[i][j] = 'E';
  464.                                 break;}
  465.                 case 'E':{    state[i][j] = 'W';
  466.                                 break;}
  467.                 }
  468.         }
  469.     }
  470.     dirFwd = !dirFwd;
  471.     return self;
  472. }
  473.  
  474. - writeRichText:(NXStream *)stream forView:view
  475. {
  476.     if(!isLinked)
  477.         NXPrintf(stream, "A %d %s", strlen(theName), theName);
  478.     else NXPrintf(stream, "B %d %s", strlen(theName), theName);
  479.     return self;
  480. }
  481. - readRichText:(NXStream *)stream forView:view 
  482. {
  483.     FILE *infile;
  484.     int i,j;
  485.     char c;
  486.     char buf[MAXPATHLEN];
  487.     
  488.     if (!etDoc) etDoc = [view etDoc];
  489.     [etDoc registerNotification:self];
  490.     NXScanf(stream, "%c %d ", &isLinked, &i);
  491.     isLinked -= 'A';
  492.     if (i) NXRead(stream, buf, i);
  493.     buf[i] = 0;
  494.     theName = NXUniqueString(buf);
  495.     if (isLinked && *buf && !access(buf,F_OK|R_OK)) {
  496.         infile = fopen(buf,"r");
  497.         fscanf(infile,"Hres %d Vres %d Reps %d\n",&hres,&vres,&i);
  498.         state = malloc(vres* sizeof(char*));
  499.         oldstate = malloc(vres* sizeof(char*));
  500.         i = -1;
  501.         while(++i < vres){
  502.             j = -1;
  503.             state[i] = malloc(hres*sizeof(char));
  504.             oldstate[i] = malloc(hres*sizeof(char));
  505.             while(++j < hres){
  506.                 fscanf(infile,"%c", &c);
  507.                 switch (c) {
  508.                     case 'O':{    state[i][j] = c;
  509.                                     break;}
  510.                     case 'N':{    state[i][j] = c;
  511.                                     break;}
  512.                     case 'S':{    state[i][j] = c;
  513.                                     break;}
  514.                     case 'W':{    state[i][j] = c;
  515.                                     break;}
  516.                     case 'E':{    state[i][j] = c;
  517.                                     break;}
  518.                     case ';':
  519.                     case '.':
  520.                     default :{    state[i][j] = '.';
  521.                                     break;}
  522.                 }
  523.             }
  524.             fscanf(infile,"%c", &c);
  525.         }
  526.         fclose(infile);
  527.         [bbcView setRes:hres :vres];
  528.         if ([bbcView window]) {
  529.             NXRect bbcRt, winRt;
  530.             
  531.             [bbcView getBounds:&bbcRt];
  532.             [[bbcView window] getBounds:&winRt];
  533.             if (bbcRt.size.width > (winRt.size.width - 72.0))
  534.                 bbcRt.size.width = (winRt.size.width - 72.0);
  535.             if (bbcRt.size.height > (winRt.size.height - 48.0))
  536.                 bbcRt.size.height = (winRt.size.height - 48.0);
  537.             [scrollView sizeTo:bbcRt.size.height :bbcRt.size.width];
  538.         }
  539.     } else {
  540.         sprintf(buf, "%s/%s.bbc", [[etDoc navinfo] path],theName);
  541.         if (access(buf,F_OK|R_OK)) {
  542.             state = malloc(vres * sizeof(char*));
  543.             oldstate = malloc(vres * sizeof(char*));
  544.             i = -1;
  545.             while(++i < vres){
  546.                 state[i] = malloc(hres*sizeof(char));
  547.                 oldstate[i] = malloc(hres*sizeof(char));
  548.                 for(j=0; j<hres; j++) state[i][j] = '.';
  549.             }
  550.             [bbcView setRes:hres :vres];
  551.             if ([bbcView window]) {
  552.                 NXRect bbcRt, winRt;
  553.                 
  554.                 [bbcView getBounds:&bbcRt];
  555.                 [[bbcView window] getBounds:&winRt];
  556.                 if (bbcRt.size.width > (winRt.size.width - 72.0))
  557.                     bbcRt.size.width = (winRt.size.width - 72.0);
  558.                 if (bbcRt.size.height > (winRt.size.height - 48.0))
  559.                     bbcRt.size.height = (winRt.size.height - 48.0);
  560.                 [scrollView sizeTo:bbcRt.size.height :bbcRt.size.width];
  561.             }
  562.         } else {
  563.             infile = fopen(buf,"r");
  564.             fscanf(infile,"Hres %d Vres %d Reps %d\n",&hres,&vres,&i);
  565.             state = malloc(vres* sizeof(char*));
  566.             oldstate = malloc(vres* sizeof(char*));
  567.             i = -1;
  568.             while(++i < vres){
  569.                 j = -1;
  570.                 state[i] = malloc(hres*sizeof(char));
  571.                 oldstate[i] = malloc(hres*sizeof(char));
  572.                 while(++j < hres){
  573.                     fscanf(infile,"%c", &c);
  574.                     switch (c) {
  575.                         case 'O':{    state[i][j] = c;
  576.                                         break;}
  577.                         case 'N':{    state[i][j] = c;
  578.                                         break;}
  579.                         case 'S':{    state[i][j] = c;
  580.                                         break;}
  581.                         case 'W':{    state[i][j] = c;
  582.                                         break;}
  583.                         case 'E':{    state[i][j] = c;
  584.                                         break;}
  585.                         case ';':
  586.                         case '.':
  587.                         default :{    state[i][j] = '.';
  588.                                         break;}
  589.                     }
  590.                 }
  591.                 fscanf(infile,"%c", &c);
  592.             }
  593.             fclose(infile);
  594.             [bbcView setRes:hres :vres];
  595.             if ([bbcView window]) {
  596.                 NXRect bbcRt, winRt;
  597.                 
  598.                 [bbcView getBounds:&bbcRt];
  599.                 [[bbcView window] getBounds:&winRt];
  600.                 if (bbcRt.size.width > (winRt.size.width - 72.0))
  601.                     bbcRt.size.width = (winRt.size.width - 72.0);
  602.                 if (bbcRt.size.height > (winRt.size.height - 48.0))
  603.                     bbcRt.size.height = (winRt.size.height - 48.0);
  604.                 [scrollView sizeTo:bbcRt.size.height :bbcRt.size.width];
  605.             }
  606.         }
  607.     }
  608.     return self;
  609. }
  610. - writeComponentToPath:(NXAtom)path inFormat:(int)theFormat
  611. {
  612.     char thePath[MAXPATHLEN];
  613.     int    i,j;
  614.     NXStream *stream;
  615.     
  616.     if (isLinked) return self;
  617.     if (theFormat != ETFD_FORMAT) return self;
  618.     sprintf(thePath,"%s/%s.bbc", path, theName);
  619.     stream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
  620.     NXPrintf(stream,"Hres %d Vres %d Reps %d\n",hres,vres, 1000);
  621.     i = -1;
  622.     while(++i < vres){
  623.         j = -1;
  624.         while(++j < hres){
  625.             NXPutc(stream, (state[i][j] == ';' ? '.' : state[i][j]));
  626.         }
  627.         NXPutc(stream,'\n');
  628.     }
  629.     NXSaveToFile(stream, thePath);
  630.     NXCloseMemory(stream, NX_FREEBUFFER);
  631.     [etDoc registerComponent:NXUniqueString(rindex(thePath, '/')+1)];
  632.     return self;
  633. }
  634. - writeASCII:(NXStream *)stream forView:view
  635. {
  636.     NXPrintf(stream, "The BBC Simulation \"%s\"\n", theName);
  637.     return self;
  638. }
  639. - writeASCIIRef:(NXStream *)stream forView:view
  640. {
  641.     int    i,j;
  642.  
  643.     NXPrintf(stream, "The BBC simulation \"%s\", in Jan's CS20 format:\n", theName);
  644.     NXPrintf(stream,"Hres %d Vres %d Reps %d\n",hres,vres, 1000);
  645.     i = -1;
  646.     while(++i < vres){
  647.         j = -1;
  648.         while(++j < hres){
  649.             NXPutc(stream, (state[i][j] == ';' ? '.' : state[i][j]));
  650.         }
  651.         NXPutc(stream,'\n');
  652.     }
  653.     return self;
  654. }
  655.  
  656.  
  657. @end